home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ohlcpio.zip
/
COPYOUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-07
|
7KB
|
232 lines
/* copyout.c - cpio copy out sub-function.
Copyright (C) 1988, 1989, 1990 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef S_IFLNK
#define lstat stat
#endif
#include <errno.h>
extern int errno;
#include <fcntl.h>
#include <sys/file.h>
#ifdef USG
#include <time.h>
#include <string.h>
#else
#include <sys/time.h>
#include <strings.h>
#endif
#include "cpio.h"
#include "dstring.h"
#include "extern.h"
/* Write out header FILE_HDR, including the file name, to file
descriptor OUT_DES. */
void
write_out_header (file_hdr, out_des)
struct cpio_header *file_hdr;
int out_des;
{
if (portability_flag)
{
char ascii_header[78];
sprintf (ascii_header,
"%06o%06o%06o%06o%06o%06o%06o%06o%011o%06o%011o",
file_hdr->h_magic & 0xFFFF, file_hdr->h_dev & 0xFFFF,
file_hdr->h_ino & 0xFFFF, file_hdr->h_mode & 0xFFFF,
file_hdr->h_uid & 0xFFFF, file_hdr->h_gid & 0xFFFF,
file_hdr->h_nlink & 0xFFFF, file_hdr->h_rdev & 0xFFFF,
file_hdr->h_mtime, file_hdr->h_namesize & 0xFFFF,
file_hdr->h_filesize);
copy_buf_out (ascii_header, out_des, 76);
/* Write file name to output. */
copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
}
else
{
/* Word align the output. */
if (output_size & 1)
copy_buf_out ("", out_des, 1);
file_hdr->h_mtimes[0] = file_hdr->h_mtime >> 16;
file_hdr->h_mtimes[1] = file_hdr->h_mtime & 0xFFFF;
file_hdr->h_filesizes[0] = file_hdr->h_filesize >> 16;
file_hdr->h_filesizes[1] = file_hdr->h_filesize & 0xFFFF;
/* Output the file header. */
copy_buf_out ((char *) file_hdr, out_des, 26);
/* Write file name to output. */
copy_buf_out (file_hdr->h_name, out_des, file_hdr->h_namesize);
/* Word align the output. */
if (file_hdr->h_namesize % 2)
copy_buf_out ("", out_des, 1);
}
}
/* Read a list of file names from the standard input
and write a cpio collection on the standard output.
The format of the header depends on the compatibility (-c) flag. */
void
process_copy_out ()
{
int res; /* Result of functions. */
dynamic_string input_name; /* Name of file read from stdin. */
long times[2]; /* For resetting file times after copy. */
struct stat file_stat; /* Stat record for file. */
struct cpio_header file_hdr; /* Output header information. */
int in_file_des; /* Source file descriptor. */
int out_file_des; /* Output file descriptor. */
/* Initialize copy out. */
ds_init (&input_name, 128);
file_hdr.h_magic = 070707;
/* Check whether the output file might be a tape. */
out_file_des = fileno (stdout);
if (fstat (out_file_des, &file_stat))
error (1, errno, "standard output is closed");
output_is_special = ((file_stat.st_mode & S_IFMT) == S_IFCHR
|| (file_stat.st_mode & S_IFMT) == S_IFBLK);
output_is_seekable = ((file_stat.st_mode & S_IFMT) == S_IFREG);
/* Copy files with names read from stdin. */
while (ds_fgets (stdin, &input_name) != NULL)
{
/* Check for blank line. */
if (input_name.ds_string[0] == 0)
{
error (0, 0, "blank line ignored");
continue;
}
/* Process next file. */
if ((*xstat) (input_name.ds_string, &file_stat) < 0)
error (0, errno, "%s", input_name.ds_string);
else
{
/* Set values in output header. */
file_hdr.h_dev = file_stat.st_dev;
file_hdr.h_ino = file_stat.st_ino;
file_hdr.h_mode = file_stat.st_mode;
file_hdr.h_uid = file_stat.st_uid;
file_hdr.h_gid = file_stat.st_gid;
file_hdr.h_nlink = file_stat.st_nlink;
file_hdr.h_rdev = file_stat.st_rdev;
file_hdr.h_mtime = file_stat.st_mtime;
file_hdr.h_filesize = file_stat.st_size;
file_hdr.h_namesize = ds_strlen (&input_name) + 1;
file_hdr.h_name = input_name.ds_string;
/* Copy the named file to the output. */
switch (file_hdr.h_mode & S_IFMT)
{
case S_IFREG:
in_file_des = open (input_name.ds_string, O_RDONLY, 0);
if (in_file_des < 0)
{
error (0, errno, "%s", input_name.ds_string);
continue;
}
write_out_header (&file_hdr, out_file_des);
copy_files (in_file_des, out_file_des, file_hdr.h_filesize);
close (in_file_des);
if (reset_time_flag)
{
times[0] = file_stat.st_atime;
times[1] = file_stat.st_mtime;
if (utime (file_hdr.h_name, times) < 0)
error (0, errno, "%s", file_hdr.h_name);
}
break;
case S_IFDIR:
file_hdr.h_filesize = 0;
write_out_header (&file_hdr, out_file_des);
break;
case S_IFCHR:
case S_IFBLK:
#ifdef S_IFSOCK
case S_IFSOCK:
#endif
#ifdef S_IFIFO
case S_IFIFO:
#endif
file_hdr.h_filesize = 0;
write_out_header (&file_hdr, out_file_des);
break;
#ifdef S_IFLNK
case S_IFLNK:
{
char *link_name = (char *) xmalloc (file_stat.st_size);
if (readlink (input_name.ds_string, link_name,
file_stat.st_size) < 0)
{
error (0, errno, "%s", input_name.ds_string);
free (link_name);
continue;
}
write_out_header (&file_hdr, out_file_des);
copy_buf_out (link_name, out_file_des, file_stat.st_size);
free (link_name);
}
break;
#endif
default:
error (0, 0, "%s: unknown file type", input_name.ds_string);
}
if (verbose_flag)
fprintf (stderr, "%s\n", input_name.ds_string);
}
}
/* The collection is complete; append the trailer. */
file_hdr.h_filesize = 0;
file_hdr.h_namesize = 11;
file_hdr.h_name = "TRAILER!!!";
write_out_header (&file_hdr, out_file_des);
/* Fill up the output block. */
while (output_size < io_block_size)
{
copy_buf_out (output_buffer, out_file_des,
(2 * output_size < io_block_size) ?
output_size : io_block_size - output_size);
}
empty_output_buffer (out_file_des);
finish_output_file ("standard output", out_file_des);
res = output_bytes / io_block_size;
if (res == 1)
fprintf (stderr, "1 block\n");
else
fprintf (stderr, "%d blocks\n", res);
}